Содержание статьи

Linux-системы обладают очень широкими возможностями для автоматизации рутинных действий. В других статьях мы уже показали массу самых разнообразных и странных примеров, включая возможность управления машиной с помощью календаря Google. Однако мы почти никогда не говорили об автоматизации и скриптовании графического софта. А ведь во многих случаях им тоже можно управлять из консоли и скриптов.
 

Wmctrl

Скрестить мощь скриптов и красоту графики поможет wmctrl. С его помощью можно изменять размер и расположение окон на экране, автоматизировать смену рабочих столов или использовать информацию об открытых окнах в других скриптах.

Основное преимущество wmctrl — полная независимость от какого-либо оконного менеджера. Он взаимодействует с окнами посредством протокола EWMH/NetWM, который поддерживают большинство оконных менеджеров.

Не буду утомлять тебя рассказами о возможностях утилиты и ее флагах, а сразу покажу пример. Все знают о существовании Yakuake и Tilda, специальных эмуляторов терминала, которые можно разворачивать и сворачивать нажатием клавиши. С помощью wmctrl ты можешь наделить такими возможностями любой другой эмулятор терминала (например, Konsole из KDE).

#! /bin/bash

if [ `wmctrl -xl | grep -c Konsole` != 0 ]; then
    if [ -f /tmp/.Konsole.add ]; then
        wmctrl -r Konsole -b add,below
        rm /tmp/.Konsole.add
    else
        wmctrl -r Konsole -b add,above
        touch /tmp/.Konsole.add
    fi
else
    konsole
fi

Просто повесь его на клавиатурную комбинацию. Первое нажатие запустит терминал, а все последующие будут сворачивать/разворачивать его.

Эмулятор терминала не единственное применение wmctrl в рамках представленного выше скрипта. На самом деле вместо Konsole можно подставить любую программу. А можно пойти дальше и задействовать в сценарии два окна, например браузер и мессенджер, таким образом, чтобы в определенный момент работы в интернете нажатием клавиш можно было заставить браузер подвинуться и освободить место под мессенджер и кинуть взгляд на сообщения в чате.

Чтобы этого добиться, сначала нужно определить размеры окон обоих приложений в каждом из двух требующихся состояний. Делается это с помощью команды wmctrl -lG (перед этим растяни/сожми окна до нужных размеров):

$ wmctrl -lG
0x0500001b  0 0    55   1280 726  N/A Проект OpenNet - QupZilla
0x03000005  0 900  55   380  693  N/A Telegram (6)

$ wmctrl -lG
0x0500001b  0 0    55   900  693  N/A Проект OpenNet - QupZilla
0x03000005  0 900  55   380  693  N/A Telegram (6)

Опция -G добавляет четыре дополнительных столбца в середине вывода команды. В них отражены данные о смещении окон по осям X и Y, а также их ширина и высота соответственно. В моем случае я сначала использовал данные в точности, как их вывела команда. Но при подстановке в сценарий расположение окна QupZilla по оси Y по какой-то причине отличалось от расчетного, поэтому его пришлось немного подкорректировать вручную.

#!/bin/sh

if [ -f /tmp/.telega.half ]; then
    wmctrl -r Telegram -e '0,900,55,380,693' -b add,below
    wmctrl -r QupZilla -e '0,0,26,1280,726'
    rm /tmp/.telega.half
else
    wmctrl -r QupZilla -e '0,0,26,900,693'
    wmctrl -r Telegram -e '0,900,55,380,693' -b remove,below
    touch /tmp/.telega.half
fi

При первом запуске этот скрипт сожмет окно браузера с правой стороны и покажет в освободившемся пространстве окно мессенджера. Второй запуск закроет мессенджер и вернет окно браузера в прежнее состояние.

Окна браузера и мессенджера на одном экране
Окна браузера и мессенджера на одном экране
 

Xdotool

Telegram, который мы использовали в примере с браузером и мессенджером, сам по себе неплохо управляется сочетаниями клавиш. И все-таки одного шортката мне не хватает. Того, который восстанавливал бы окно из лотка. Wmctrl не всегда способен решить эту задачу. И пока встроенные возможности мессенджера не могут нас порадовать подобной функциональностью, поможет утилита xdotool. Она позволяет эмулировать действия мышью, а значит, и повесить их на сочетания клавиш.

Поскольку рабочее окружение у меня Plasma, я создал еще один виджет системного лотка, отключив в его настройках все пункты, кроме «Состояния приложений», а всем элементам приложений, кроме Telegram, указал пожизненную невидимость («Всегда скрывать»). Сам же Telegram должен быть всегда виден.

Настройки второго системного лотка
Настройки второго системного лотка

Осталось только определить координаты значка «Телеграма» при заблокированных виджетах, установив на него курсор мыши и выполнив в терминале такую команду:

$ xdotool getmouselocation
Получение координат курсора
Получение координат курсора

Из всего многообразия полученных данных берем координаты X, Y (в моем случае — 1238 и 776) и подставляем в команду, перемещающую курсор мыши в заданное положение из любой области экрана и эмулирующую одно нажатие левой кнопки.

#!/bin/sh

xdotool mousemove 1238 776 click 1 mousemove 640 400

Далее скрипт можно привязать к комбинации клавиш (или, как у меня, к одной — Menu), чтобы при их нажатии появлялось окно программы. Повторное нажатие того же сочетания клавиш вновь свернет окно Telegram в трей. Для удобства навигации в скрипт добавлен возврат курсора мыши в центр экрана.

 

Xwininfo

Утилита xwininfo показывает на экране большое количество характеристик выбранного окна: ID, название, размеры, отступы от краев экрана, толщину границ, цветовую палитру и многое другое. Утилита wmctrl, содержащая в строке параметров опцию :SELECT:, позволяет применить указанные параметры к окну, наведя на него курсор и щелкнув мышью:

$ wmctrl -r :SELECT: -T <название>

 

Xprop

Часто используемая в различных сценариях утилита xprop предназначена для отображения свойств окон и шрифтов. В некоторых моментах функциональность xprop пересекается с функциональностью других утилит. Например, чтобы определить активное окно, можно выполнить одну из следующих команд:

$ xdotool getwindowname $(xdotool getactivewindow)

$ xwininfo -int -id $(xdotool getactivewindow) | awk -F\" '/xwininfo:/ { print $2; exit }'

$ xwininfo -id $(xprop -root | awk '/NET_ACTIVE_WINDOW/ { print $5; exit }') | awk -F\" '/xwininfo:/ { print $2; exit }'

Кроме того, xprop можно использовать, когда нужно изменить свойства окон или шрифтов. В одной из прошлых статей я рассказывал про трюк с эффектом размытия для полупрозрачного окна Yakuake. Тот же прием для Konsole будет выглядеть так:

#!/bin/bash

if [ `echo $DISPLAY` ]; then
    konsolex=$(qdbus | grep konsole | cut -f 2 -d\ )
    if [ -n konsolex ]; then
        for konsole in $konsolex; do
            xprop -f _KDE_NET_WM_BLUR_BEHIND_REGION 32c -set _KDE_NET_WM_BLUR_BEHIND_REGION 0 -id `qdbus $konsole /konsole/MainWindow_1 winId`;
        done
    fi
fi
 

D-Bus

Практически любой современный десктопный дистрибутив Linux поставляется с системой межпроцессного взаимодействия D-Bus. Многие приложения используют D-Bus для общения между собой, ее же использует среда KDE с версии 4. Для нас же важно то, что D-Bus можно применить в качестве посредника между пользователем и машиной, то есть для управления графическими приложениями и их скриптования.

Как пример использования D-Bus приведу скрипт, который мониторит уведомления от Telegram и при наличии в сообщении определенного триггера — имени контакта или ключевой фразы — автоматически открывает приложение для просмотра сообщения. Чтобы реализовать этот замысел, можно присовокупить к D-Bus уже известный нам xdotool:

#!/bin/bash

contact="Николай"

dbus-monitor "interface='org.freedesktop.Notifications'" |\
grep --line-buffered "string" |\
grep --line-buffered $contact |\
grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v |\
grep --line-buffered '.*(?=string)|(?<=string).*' -oPi |\
grep --line-buffered -v '^\s*$' |\
xargs -I '{}' echo {} |\

sed -u -n 's/'$contact'/xdotool mousemove 1096 66 sleep 1 click 1/p' |\

sh

В качестве триггера здесь использовано имя контакта, как оно указано в списке контактов. Фильтруя и редактируя новые сообщения в рамках мониторинга D-Bus, на выходе получаем имя контакта в момент, когда от него приходит сообщение, и подменяем его на модифицированную команду из предыдущих примеров.

По заранее вычисленным координатам скрипт перемещает курсор мыши в ту область, где появляется окно нотификации, и секунду спустя эмулирует клик левой кнопки, тем самым заставляя «Телеграм» открываться с фокусом на отправителе этого сообщения и самом сообщении.

 

Выводы

Несмотря на то что графический софт обычно предполагает управление мышью и зачастую весьма ограниченный набор комбинаций клавиш, широкие возможности Linux позволяют создавать сценарии даже в этом случае.

В статье перечислены далеко не все возможности консольных приложений по управлению программами с графическим интерфейсом. Тут предпринята всего лишь попытка обозначить наиболее общие моменты, с помощью которых каждый мог бы настроить собственный инструментарий для выполнения своих уникальных задач.

Оцени статью:

Что тебе понравилось больше всего?
Что тебе не понравилось больше всего?